// ============================================
// 04 - 流程控制 (Control Flow)
// ============================================

/// Rust 提供了多种控制流结构来改变代码的执行顺序

// ==================== 条件语句 ====================

/// if 表达式
/// Rust 中的 if 是表达式，可以返回值
pub fn if_expressions() {
    println!("\n=== if 表达式 ===");
    
    // 基本 if 语句
    let number = 7;
    if number < 5 {
        println!("条件为真");
    } else {
        println!("条件为假");
    }
    
    // if-else if-else
    let number = 6;
    if number % 4 == 0 {
        println!("{} 能被 4 整除", number);
    } else if number % 3 == 0 {
        println!("{} 能被 3 整除", number);
    } else if number % 2 == 0 {
        println!("{} 能被 2 整除", number);
    } else {
        println!("{} 不能被 4、3、2 整除", number);
    }
    
    // if 作为表达式返回值
    let condition = true;
    let number = if condition { 5 } else { 6 };
    println!("number 的值是: {}", number);
    
    // 注意: if 和 else 分支必须返回相同类型
    // let error = if condition { 5 } else { "six" }; // ❌ 编译错误
}

/// match 表达式
/// match 必须穷尽所有可能性
pub fn match_expressions() {
    println!("\n=== match 表达式 ===");
    
    // 基本 match 使用
    let number = 3;
    match number {
        1 => println!("一"),
        2 => println!("二"),
        3 => println!("三"),
        4 => println!("四"),
        5 => println!("五"),
        _ => println!("其他"), // _ 是通配符，匹配所有其他值
    }
    
    // match 返回值
    let number = 2;
    let chinese_number = match number {
        1 => "一",
        2 => "二",
        3 => "三",
        4 => "四",
        5 => "五",
        _ => "其他",
    };
    println!("数字 {} 对应: {}", number, chinese_number);
    
    // 多个模式
    let number = 5;
    match number {
        1 | 3 | 5 | 7 | 9 => println!("{} 是奇数", number),
        2 | 4 | 6 | 8 | 10 => println!("{} 是偶数", number),
        _ => println!("不在范围内"),
    }
    
    // 范围匹配
    let number = 13;
    match number {
        1..=5 => println!("{} 在 1-5 之间", number),
        6..=10 => println!("{} 在 6-10 之间", number),
        11..=15 => println!("{} 在 11-15 之间", number),
        _ => println!("{} 超出范围", number),
    }
}

/// match 守卫
/// 使用 if 添加额外的匹配条件
pub fn match_guards() {
    println!("\n=== match 守卫 ===");
    
    let number = 4;
    match number {
        n if n < 0 => println!("{} 是负数", n),
        n if n == 0 => println!("零"),
        n if n % 2 == 0 => println!("{} 是正偶数", n),
        n => println!("{} 是正奇数", n),
    }
    
    let pair = (2, -2);
    match pair {
        (x, y) if x == y => println!("相等"),
        (x, y) if x + y == 0 => println!("互为相反数"),
        (x, _) if x % 2 == 0 => println!("第一个数是偶数"),
        _ => println!("其他情况"),
    }
}

/// 解构匹配
pub fn destructuring_match() {
    println!("\n=== 解构匹配 ===");
    
    // 匹配元组
    let point = (3, 5);
    match point {
        (0, 0) => println!("原点"),
        (0, y) => println!("在 y 轴上，y = {}", y),
        (x, 0) => println!("在 x 轴上，x = {}", x),
        (x, y) => println!("坐标: ({}, {})", x, y),
    }
    
    // 匹配枚举
    let direction = Direction::North;
    match direction {
        Direction::North => println!("向北"),
        Direction::South => println!("向南"),
        Direction::East => println!("向东"),
        Direction::West => println!("向西"),
    }
}

#[derive(Debug)]
enum Direction {
    North,
    South,
    East,
    West,
}

/// if let 表达式
/// 当只关心一种匹配情况时使用
pub fn if_let_expressions() {
    println!("\n=== if let 表达式 ===");
    
    let some_value = Some(7);
    
    // 使用 match
    match some_value {
        Some(7) => println!("得到了 7"),
        _ => (),
    }
    
    // 使用 if let 更简洁
    if let Some(7) = some_value {
        println!("得到了 7");
    }
    
    // if let 配合 else
    let some_value = Some(5);
    if let Some(7) = some_value {
        println!("得到了 7");
    } else {
        println!("没有得到 7");
    }
    
    // 实际应用例子
    let config_max = Some(3);
    if let Some(max) = config_max {
        println!("最大值配置为: {}", max);
    }
}

/// while let 表达式
pub fn while_let_expressions() {
    println!("\n=== while let 表达式 ===");
    
    let mut stack = vec![1, 2, 3, 4, 5];
    
    // 使用 while let 遍历
    println!("弹出元素:");
    while let Some(top) = stack.pop() {
        println!("  {}", top);
    }
}

// ==================== 循环 ====================

/// loop 循环
/// 无限循环，除非使用 break 退出
pub fn loop_loops() {
    println!("\n=== loop 循环 ===");
    
    // 基本 loop
    let mut counter = 0;
    loop {
        counter += 1;
        if counter == 5 {
            println!("计数到 {} 后退出", counter);
            break;
        }
    }
    
    // loop 返回值
    let mut counter = 0;
    let result = loop {
        counter += 1;
        if counter == 10 {
            break counter * 2; // 从 loop 返回值
        }
    };
    println!("loop 返回值: {}", result);
    
    // 循环标签
    let mut count = 0;
    'outer: loop {
        println!("外层循环 count = {}", count);
        let mut remaining = 10;
        
        loop {
            println!("  内层循环 remaining = {}", remaining);
            if remaining == 9 {
                break; // 退出内层循环
            }
            if count == 2 {
                break 'outer; // 退出外层循环
            }
            remaining -= 1;
        }
        
        count += 1;
    }
    println!("退出循环");
}

/// while 循环
/// 条件循环
pub fn while_loops() {
    println!("\n=== while 循环 ===");
    
    // 基本 while 循环
    let mut number = 3;
    while number != 0 {
        println!("{}!", number);
        number -= 1;
    }
    println!("发射！");
    
    // while 遍历数组 (不推荐)
    let a = [10, 20, 30, 40, 50];
    let mut index = 0;
    
    println!("使用 while 遍历数组:");
    while index < a.len() {
        println!("  值为: {}", a[index]);
        index += 1;
    }
}

/// for 循环
/// 遍历集合
pub fn for_loops() {
    println!("\n=== for 循环 ===");
    
    // 遍历数组
    let a = [10, 20, 30, 40, 50];
    println!("遍历数组:");
    for element in a.iter() {
        println!("  值为: {}", element);
    }
    
    // 遍历范围
    println!("倒计时:");
    for number in (1..=3).rev() {
        println!("  {}!", number);
    }
    println!("发射！");
    
    // 普通范围遍历
    println!("0 到 4:");
    for i in 0..5 {
        print!("{} ", i);
    }
    println!();
    
    // 包含结束值的范围
    println!("1 到 5:");
    for i in 1..=5 {
        print!("{} ", i);
    }
    println!();
    
    // 枚举索引和值
    println!("带索引遍历:");
    for (index, value) in a.iter().enumerate() {
        println!("  索引 {}: 值 {}", index, value);
    }
}

/// continue 和 break
pub fn continue_and_break() {
    println!("\n=== continue 和 break ===");
    
    // continue - 跳过当前迭代
    println!("跳过偶数:");
    for i in 1..=10 {
        if i % 2 == 0 {
            continue; // 跳过偶数
        }
        print!("{} ", i);
    }
    println!();
    
    // break - 提前退出循环
    println!("找到第一个大于 50 的数:");
    for i in 1..=100 {
        if i > 50 {
            println!("找到: {}", i);
            break;
        }
    }
    
    // 嵌套循环中的 continue 和 break
    println!("九九乘法表 (前 5 行):");
    'outer: for i in 1..=9 {
        for j in 1..=i {
            print!("{}x{}={:2}  ", j, i, i * j);
        }
        println!();
        if i >= 5 {
            break 'outer;
        }
    }
}

/// 循环性能比较
pub fn loop_performance() {
    println!("\n=== 循环性能 ===");
    
    let numbers = vec![1, 2, 3, 4, 5];
    
    // for 循环是最优选择
    let mut sum = 0;
    for num in &numbers {
        sum += num;
    }
    println!("使用 for 循环求和: {}", sum);
    
    // 使用迭代器更高效
    let sum: i32 = numbers.iter().sum();
    println!("使用迭代器求和: {}", sum);
}

/// 实际应用示例
pub fn practical_examples() {
    println!("\n=== 实际应用示例 ===");
    
    // 查找数组中的最大值
    let numbers = [34, 50, 25, 100, 65];
    let mut max = numbers[0];
    for &num in &numbers {
        if num > max {
            max = num;
        }
    }
    println!("最大值: {}", max);
    
    // 计算阶乘
    let n = 5;
    let mut factorial = 1;
    for i in 1..=n {
        factorial *= i;
    }
    println!("{}! = {}", n, factorial);
    
    // 判断素数
    let num = 17;
    let mut is_prime = true;
    if num < 2 {
        is_prime = false;
    } else {
        for i in 2..num {
            if num % i == 0 {
                is_prime = false;
                break;
            }
        }
    }
    println!("{} {} 素数", num, if is_prime { "是" } else { "不是" });
}

/// 主函数 - 演示所有功能
#[allow(dead_code)]
pub fn main() {
    println!("╔════════════════════════════════════════╗");
    println!("║   Rust 流程控制教程                    ║");
    println!("╚════════════════════════════════════════╝");
    
    if_expressions();
    match_expressions();
    match_guards();
    destructuring_match();
    if_let_expressions();
    while_let_expressions();
    loop_loops();
    while_loops();
    for_loops();
    continue_and_break();
    loop_performance();
    practical_examples();
    
    println!("\n✅ 流程控制教程完成！");
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_match_expression() {
        let number = 3;
        let result = match number {
            1 => "one",
            2 => "two",
            3 => "three",
            _ => "other",
        };
        assert_eq!(result, "three");
    }
    
    #[test]
    fn test_if_expression() {
        let condition = true;
        let number = if condition { 5 } else { 6 };
        assert_eq!(number, 5);
    }
    
    #[test]
    fn test_loop_return() {
        let mut counter = 0;
        let result = loop {
            counter += 1;
            if counter == 10 {
                break counter * 2;
            }
        };
        assert_eq!(result, 20);
    }
}

